#pragma once
#include <QFrame>
#include <QJsonArray>
#include <QJsonObject>
#include <functional>

#include "widgets.h"

#define ITEM_DEFAULT_HEIGHT 25

class QAbstractItemDelegate;
class IKeySearchEngine {
 public:
  virtual void search(int serialNum, const QString& key) = 0;
  virtual void setUserData(int userdata) = 0;
  virtual void setResultCallback(std::function<void(int, QJsonArray)> fun) = 0;
  virtual void onResultSelected(const QString& key) = 0;
};

class KeySearchEdit;
class KeySearchResultDlg;
class DefaultItemDelegate;
class SImageButton;
class S_WIDGETS_EXPORT KeySearchWidget : public QFrame {
  Q_OBJECT
 public:
  KeySearchWidget(QWidget* parent, const QString& bgName,
                  const QString& bgHoverName, const QString& borderName,
                  int margin = 0, bool showBorder = false,
                  int itemHeight = ITEM_DEFAULT_HEIGHT, int fontSize = 10);

  void setSearchText(const QString& txt, bool blockSignal = false);
  void appendSearchText(const QString& txt);
  void setPromptText(const QString& txt);
  void setResultItemDelegate(QAbstractItemDelegate* itemDelegate);
  void setResultDlgMaxHeight(int h);
  void setResultDlgMinWidth(int w);
  void setColumnsWidth(int count, ...);
  void setSearchWhenEmpty(bool v);
  void setSearchEngine(IKeySearchEngine* se);
  void setEditFocus();
  void setAutoSelect(bool bAutoSelect);
  void setAutoKillFocus(bool bAutoKillFocus);
  void setSearchEnable(bool enable);
  void setEditFocusChangedClearText(bool clear);
  IKeySearchEngine* searchEngine() { return m_searchEngine; }
  void foucsChanged(bool v);
  void hideResult();
  void clearEditFocus();

  QString getSearchKey();
 signals:
  void itemClicked(QJsonValue obj);
  void resultReached(QJsonArray results);
  void resultHide();
  void searchFocusChanged(bool v);
  void resultClear();

 protected slots:
  void onSearchTextChanged(const QString& searchKey);
  void onResultReach(int, QJsonArray results);

 protected:
  virtual void resizeEvent(QResizeEvent*) override;

 private:
  KeySearchEdit* m_edit = nullptr;
  KeySearchResultDlg* m_resultDlg = nullptr;
  IKeySearchEngine* m_searchEngine = nullptr;
  DefaultItemDelegate* m_delegate = nullptr;
  SImageButton* m_label = nullptr;
  bool m_searchWhenEmpty = false;
  bool m_showBorder = false;
  bool m_editFocusChangedClearText = true;
  bool m_blockSignal = false;
  uint32_t m_searchSerialNum = 0;
  QString m_promptText;
  QString m_bgName;
  QString m_bgHoverName;
  QString m_borderName;
  int m_widthResult = 0;
};